package com.gopay.checkorder.service.impl.bcdl;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.dao.BankBcdlOrderDAO;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BcdlMessage;
import com.gopay.common.domain.bank.BcdlQueryBalance;
import com.gopay.common.domain.bank.BcdlResult;
import com.gopay.common.domain.bis.BisBankBcdlOrder;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.BcdlInteractRemoteService;

public class CheckBcdlOrderCcbImpl extends BaseBcdlOrderProcessImpl {
	private final static Logger logger = LoggerFactory.getLogger("CCB");
	@Resource(name = "bankBcdlClient")
	private BcdlInteractRemoteService bankBcdlClient;
	@Resource(name = "bankBcdlOrderDAO")
	private BankBcdlOrderDAO bankBcdlOrderDAO;
	
	@Override
	public BcdlResult queryBalance(BcdlQueryBalance queryOrder) {
		// TODO Auto-generated method stub
		BcdlResult result = new BcdlResult();
        try {
            BcdlMessage base = buildQryBalanceMsg(queryOrder);
            base.setLabel("QUERY_0");
            logger.info("ccb bcdl query balance send bank orderId: " + queryOrder.getQueryOrderId());
            result = bankBcdlClient.sendBankQueryBalance(base);
            return result;
        } catch (Exception e) {
            logger.error("银企直连订单查询余额失败: " + queryOrder.getQueryOrderId(), e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6027);
            return result;
        }
	}
	
	@Override
	public CheckOrderResult checkOrder(BankOrder bankOrder, String target) {
		// TODO Auto-generated method stub
		CheckOrderResult checkOrderResult = new CheckOrderResult();
		try {
			checkOrderResult.setSuccess(false);
			checkOrderResult.setOrderId(bankOrder.getOrderId());

			BcdlMessage base = new BcdlMessage();
			BisBankBcdlOrder bcdl = bankBcdlOrderDAO
					.findBankBcdlOrderById(bankOrder.getOrderId());
			base.setBankOrderId(bankOrder.getOrderId());
			base.setOrderId(bankOrder.getOrderId());// 使用订单号
			base.setOutOrderId(bankOrder.getOutOrderId());// 使用外部订单号
			base.setBank(bankOrder.getBankCode());
			base.setDcblType(bcdl.getBcFlag());
			base.setLabel("QUERY_0");
			BcdlResult result = new BcdlResult();
			logger.error("boc bcdl check order BcdlMessage: " + ToStringBuilder.reflectionToString(base,
					ToStringStyle.DEFAULT_STYLE));
			result = bankBcdlClient.query(base);
			
			logger.error("bcdl check order result: " + result);

			//modified by zyt,2017-10-10, 将result为空和其他情况分开写，解决之前null中依然get的潜在空指针
			if (result == null) {
				logger.error("boc bcdl bankBcdlClient fail. result is null");
				return checkOrderResult;
			} else if (result.getDefaultModel() == null){
				logger.error("boc bcdl bankBcdlClient fail.");
				logger.error(ToStringBuilder.reflectionToString(result,
						ToStringStyle.DEFAULT_STYLE));

				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg("bis query is null.");
				return checkOrderResult;
			}
			//add by zyt,2017-9-26,根绝返回结果设置checkorderResult的needRefund值
			checkOrderResult.setNeedRefund(result == null ? false : result.isNeedRefund());

			if (!result.isSuccess()) {
				if(ProcCodeConstants.PROC_CODE_100E6027.equals(result.getResultCode())){
					//业务异常
					logger.error("boc bcdl orderId:" + bankOrder.getOrderId()
							+ " errcode:" + ProcCodeConstants.PROC_CODE_100E6027
							+ " err:bis order is fail.");
					checkOrderResult.setBankFailure(true);
					checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6027);
					checkOrderResult.setBankRetCode(result.getBankRetCode());
					checkOrderResult.setErrMsg(result.getErrorMsg());
					return checkOrderResult;
				}else{
					//签到异常 50 返回异常(xml为空等) 49 其他异常 47
					logger.error("boc bcdl orderId: " + bankOrder.getOrderId()
							+ " state is not success, resultCode: " + result.getResultCode());
					checkOrderResult.setErrCode(result.getResultCode());
					checkOrderResult.setErrMsg(StringUtils.isNotBlank(result.getErrorMsg()) ? result.getErrorMsg() : result
							.getResultCode());
					checkOrderResult.setBankRetCode(result.getBankRetCode());
					return checkOrderResult;
				}
			}else{
				//返回成功
				InAccInfo accInfo = new InAccInfo();
				accInfo.setOrderId(bankOrder.getOrderId());
				CpsGenMainOrder mainOrder = getMainOrder(bankOrder.getOrderId());
				accInfo.setAmount(mainOrder.getMerTxnAmt());
				accInfo.setRetCode("00");
				accInfo.setCardType(BankCardType.Unknown.toString());
				checkOrderResult.setAccInfo(accInfo);
				checkOrderResult.setSuccess(true);
				checkOrderResult
						.setErrCode(ProcCodeConstants.PROC_CODE_100S1000);
				return checkOrderResult;
			}
		} catch(Exception e){
			logger.error("CheckBcdlOrderBocImpl error: " + bankOrder.getOrderId(), e);
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
			checkOrderResult.setErrMsg("bis is too busy.");
			return checkOrderResult;
		}
	}
	
	@Override
	public BcdlResult sendBank(BankOrder bankOrder){
		BcdlResult result = new BcdlResult();
		try {
			BcdlMessage base = buildMsg(bankOrder);
			logger.info("boc bcdl send bank orderId: " + bankOrder.getOrderId());
			result = bankBcdlClient.sendBank(base);
			return result;
		} catch (Exception e) {
			logger.error("银企直连订单支付失败: " + bankOrder.getOrderId(), e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
			return result;
		}
	}
	
	public BcdlResult sendBank(BankOrder bankOrder, String label) {
		BcdlResult result = new BcdlResult();
		try {
			BcdlMessage base = buildMsg(bankOrder);
			base.setLabel(label);
			logger.info("ccb bcdl send bank orderId: " + bankOrder.getOrderId());
			result = bankBcdlClient.sendBank(base);
			return result;
		} catch (Exception e) {
			logger.error("银企直连订单支付失败: " + bankOrder.getOrderId(), e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
			return result;
		}
	}
	
	private BcdlMessage buildMsg(BankOrder bankOrder) throws GopayException {
		BcdlMessage bcdlMsg = new BcdlMessage();
		BisBankBcdlOrder bcdl = bankBcdlOrderDAO
				.findBankBcdlOrderById(bankOrder.getOrderId());
		ToStringBuilder.reflectionToString(bcdl);
		bcdlMsg.setBankBusProd(BisBankBusinessProd._09);
		bcdlMsg.setBank(bankOrder.getBankCode());
		bcdlMsg.setBankIntrChann(BisBankInterfaceChannel._00);
		bcdlMsg.setGopayBankOrderNo(bankOrder.getOrderId());
		bcdlMsg.setOrderId(bankOrder.getOrderId());
		bcdlMsg.setOutOrderId(bankOrder.getOutOrderId());

		bcdlMsg.setPobcBankCode(bcdl.getRecvPbocBankCode());// 央行代码
		bcdlMsg.setPbocBankName(bcdl.getRecvBankName());// 央行名称
		bcdlMsg.setPbocBankBranchCode(bcdl.getRecvBankPbocNum());// 联行号
		bcdlMsg.setPbocBankBranchName(bcdl.getRecvBankBranchName());// 联行名
		bcdlMsg.setRecvBankAcctNum(bcdl.getRecvBankAcctNum());// 账号
		bcdlMsg.setRecvBankAcctName(bcdl.getRecvBankAcctName());// 户名
		bcdlMsg.setRecvBankProvNo(bcdl.getRecvBankProvinceCode());// 省代码
		bcdlMsg.setRecvBankProvName(bcdl.getRecvBankProvinceName());// 省名称
		bcdlMsg.setRecvBankCityCode(bcdl.getRecvBankCityCode());// 城市代码
		bcdlMsg.setRecvBankCityName(bcdl.getRecvBankCityName());// 城市名称
		bcdlMsg.setDcblType(bcdl.getBcFlag());
		bcdlMsg.setSysIOFlg(bcdl.getCrossBank());
		bcdlMsg.setEmergency(bcdl.getUrgent());
		int sameCity = 0;
		if (StringUtils.equals(bcdlMsg.getRecvBankProvNo(), "01")
				|| (bcdlMsg.getRecvBankProvName() != null && bcdlMsg
						.getRecvBankProvName().indexOf("北京") != -1)) {
			sameCity = 1;
		}
		bcdlMsg.setIsSameCity(sameCity);
		CpsGenMainOrder mainOrder = getMainOrder(bankOrder.getOrderId());
        if(mainOrder.getSettleAmt()==null){
            throw new RuntimeException("bcdl结算金额为null");
        }
        bcdlMsg.setAmount(mainOrder.getSettleAmt());
		return bcdlMsg;
	}
	
	private BcdlMessage buildQryBalanceMsg(BcdlQueryBalance qryOrder) {
        BcdlMessage bcdlMsg = new BcdlMessage();
        bcdlMsg.setBank(qryOrder.getQueryBankCode());
        bcdlMsg.setOrderId(qryOrder.getQueryOrderId());
        return bcdlMsg;
    }
}
